# Create your views here.
from django.http import HttpResponse, Http404, HttpResponseRedirect
#from django.template import Context, loader
from django.conf import settings
from django.shortcuts import render_to_response
import urllib
import srb
import os
import mimetypes

# The following need to be set in the site settings.py file:
# SRB_MDAS_ROOT - The directory with the .MdasEnv 
#                 and .MdasAuth files
# SRB_ROOT - The SRB collection that's being mounted

SRB_MAX_TRANSFER_BLOCK_SIZE = srb.constants.SRB_MAX_TRANSFER_BLOCK_SIZE
DATA_NAME = srb.constants.mcat.DATA_NAME
SIZE = srb.constants.mcat.SIZE

srbKeyWords = ["srbUser", "srbHost", "mdasDomainName", "srbPort", "AUTH_SCHEME", "password",
               "SERVER_DN", "mdasDomainName", "mcatZone", "mdasResourceName", "defaultResource"]

def __getConnectionData(failed=False):
    path = settings.SRB_MDAS_ROOT
    conData = {}
    defaults = False
    MdasEnv = ".MdasEnv"
    MdasAuth = ".MdasAuth"
    authSchemes = ["ENCRYPT1"]
        
    def readDefaults(path):
        defaults = {}
        inD = open(os.path.join(path,MdasEnv))
        for line in inD:
            item = line.split()
            if len(item) == 2:
                defaults[item[0]] = item[1].strip("'")
        inD.close()
        inD = open(os.path.join(path,MdasAuth))
        defaults["password"] = inD.read()
        inD.close()
        return defaults 
                                
    def testPath(tPath):
        if os.path.exists(os.path.join(tPath,MdasEnv)) and \
                os.path.exists(os.path.join(tPath,MdasAuth)):
            return True
        return False
       
    if testPath(path) and not failed:
        conData = readDefaults(path)

    for i in srbKeyWords:
        if not conData.has_key(i):
            conData[i] = ""
    return conData
    
def getConnection(): 

    fail = False
    conn_id = -1
    con_data = None
    while conn_id < 0:
        con_data = __getConnectionData(failed = fail)

        #srbKeyWords = ["srbUser", "srbHost", "mdasDomainName", "srbPort", "AUTH_SCHEME", "password",
        #               "domain", "mdasDomainName", "mcatZone", "mdasResourceName", "defaultResource"]

        conn_id = srb.connect(con_data["srbHost"], con_data["srbPort"],
                              con_data["mdasDomainName"], con_data["AUTH_SCHEME"], 
                              con_data["srbUser"], con_data["password"], 
                              con_data["SERVER_DN"])

        fail = True

    return (conn_id, con_data)


class SRBObjIterator:
    def __init__(self, conn_id, srb_path):

        self.conn_id = conn_id
        coll_name = os.path.dirname(srb_path)
        obj_name = os.path.basename(srb_path)

        obj_found = False
        self.obj_size = -1
        num = srb.get_objs_in_coll(self.conn_id, 0, 16400, coll_name)
        if num < 0:
            raise Exception

        while num > 0:
            for x in range(0, num):
                if srb.get_obj_metadata(self.conn_id, DATA_NAME, x) == obj_name:
                    self.obj_size = int(srb.get_obj_metadata(self.conn_id, SIZE, x))
                    obj_found = True
                    break
            if obj_found:
                break
            num = srb.more_objs_in_coll(self.conn_id)

        if not obj_found:
            raise Http404
        if self.obj_size <= 0:
            raise Exception

        self.bytes_to_read = self.obj_size
        self.fd = srb.obj_open(self.conn_id, coll_name, obj_name, srb.constants.O_RDONLY)

        if self.fd < 0:
            raise Exception

    def next(self):

        if self.bytes_to_read == 0:
            raise StopIteration            

        if self.bytes_to_read < SRB_MAX_TRANSFER_BLOCK_SIZE:
            obj_data = srb.obj_read(self.conn_id, self.fd, self.bytes_to_read)
            self.bytes_to_read = 0
            # object read, close connection
            status = srb.obj_close(self.conn_id, self.fd)
            if status < 0:
                raise Exception
            srb.disconnect(self.conn_id)
        else:

            obj_data = srb.obj_read(self.conn_id, self.fd, SRB_MAX_TRANSFER_BLOCK_SIZE)
            self.bytes_to_read -= SRB_MAX_TRANSFER_BLOCK_SIZE
        
        return obj_data

    def __iter__(self):
        return self

def getCollectionListing(conn_id, srb_path):

    # put path in a format the srb code likes
    if len(srb_path) > 1 and srb_path[-1] == '/':
        srb_path = srb_path[:-1]

    listing = []

    # start with sub collections, if any
    num = srb.get_subcolls(conn_id, 0, srb_path)
    while num > 0:
        for x in range(0, num):
            subcoll_name = srb.get_subcoll_name(conn_id, x)
            subcoll_name = subcoll_name[len(srb_path + '/'):]
            listing.append({'name':subcoll_name + '/',
                            'urlname':urllib.pathname2url(subcoll_name + '/'),
                            'date':'',
                            'size':''})
        num = srb.more_subcolls(conn_id)

    # get objects
    num = srb.get_objs_in_coll(conn_id, 0, 16400 , srb_path)
    while num > 0:
        for x in range(0, num):
            obj_name = srb.get_obj_metadata(conn_id, srb.constants.mcat.DATA_NAME, x)
            date_mod = srb.get_obj_metadata(conn_id, srb.constants.mcat.REPL_TIMESTAMP, x)
            obj_size = int(srb.get_obj_metadata(conn_id, srb.constants.mcat.SIZE, x))
            listing.append({'name':obj_name,
                            'urlname':urllib.pathname2url(obj_name),
                            'date':date_mod,
                            'size':'%d' % obj_size})

        num = srb.more_objs_in_coll(conn_id)

    return listing

def get(request, path):

    srb_path = os.path.join(settings.SRB_ROOT, path)

    conn_id, con_dat = getConnection()
    if conn_id < 0:
        raise Exception

    if srb.is_object(conn_id, srb_path):
        srb_obj_iter = SRBObjIterator(conn_id, srb_path)
        mime_type, encode = mimetypes.guess_type(srb_path)
        response = HttpResponse(srb_obj_iter, mimetype=mime_type)
        response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(path)
        response['Content-Length'] = srb_obj_iter.obj_size
        if encode:
            response['Content-Encoding'] = encode
        if mime_type:
            response['Content-Type'] = mime_type

    elif srb.is_collection(conn_id, srb_path):
        # if it's a collection, make sure we're using a url with a trailing slash
        # this is just to pick something and be consitent with it
        if srb_path[-1] != '/':
            return HttpResponseRedirect(os.path.basename(path) + '/')
        listing = {'path':srb_path[len(settings.SRB_ROOT):]}
        #response = HttpResponse("Should be a collection", mimetype="text/plain")
        listing['items'] = getCollectionListing(conn_id, srb_path)
        #listing = [{'name':'%s, %d' % (srb_path, len(listing))}]
        srb.disconnect(conn_id)
        return render_to_response('django_srb/browser/index.html', {'listing': listing})
    else:
        srb.disconnect(conn_id)
        raise Http404

    return response
